#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> 
#include <arpa/inet.h>
#include <unistd.h>

/***建立客户端***/
/*
1、建立套接字
2、绑定本地IP地址和端口号
3、连接服务器
4、和服务器进行通信
5、关闭套接字
*/

#define OWN_IP      "192.168.231.130"       //ubuntu 本地的ip地址，作为客户端
#define OWN_PORT    5000                    //ubuntu 本地的端口号，作为客户端

#define SERVER_IP   "192.168.231.130"         //对方的ip地址，作为服务端
#define SERVER_PORT 5001                    //对方的端口号，作为服务端

int main(void)
{
    int socket_fd = 0;
    socket_fd = socket(AF_INET, SOCK_STREAM, 0);        //建立套接字
    if(-1 == socket_fd)
    {
        perror("socket error");
        return -1;
    }


    struct sockaddr_in own_addr;                        //定义一个IPv4结构体变量，初始化自己的（客户端）的ip地址、端口号
    own_addr.sin_family = AF_INET;
    own_addr.sin_addr.s_addr = inet_addr(OWN_IP);
    own_addr.sin_port = htons(OWN_PORT);

    int ret = 0;                                        //绑定自己的（客户端）的ip地址、端口号
    ret = bind(socket_fd, (struct sockaddr *)&own_addr, sizeof(struct sockaddr));
    if(-1 == ret)
    {
        perror("bind error");
        return -1;
    }

    char *own_ip = inet_ntoa(own_addr.sin_addr);        //ip地址：网络ip---->本地ip
    uint16_t own_port = ntohs(own_addr.sin_port);       //端口号：网络端口号---->本地端口号

    printf("Successfully bind to local: [%s][%d]\n", own_ip, own_port);

    struct sockaddr_in server_addr;                        //定义一个IPv4结构体变量，初始化服务端的ip地址、端口号
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
    server_addr.sin_port = htons(SERVER_PORT);

                                                            //连接服务器
    ret = connect(socket_fd, (struct sockaddr *)&server_addr, sizeof(server_addr));
    if(-1 == ret)
    {
        perror("connect error");
        return -1;
    }

    char *server_ip = inet_ntoa(server_addr.sin_addr);      //ip地址：网络ip---->本地ip
    uint16_t server_port = ntohs(server_addr.sin_port);     //端口号：网络端口号---->本地端口号

    printf("The server is successfully connected: [%s][%d]\n", server_ip, server_port);

    char buf[1024] = {0};

    pid_t pid = fork();                                   //创建子进程，返回值是子进程的pid
    if(-1 == pid)
    {
        perror("fork error");
        return -1;
    }

    if(pid > 0)                                           //该进程为父进程，用于向服务端发送消息
    {
        while(true)
        {
            memset(buf, 0, sizeof(buf));
            printf("Send the message to the server: ");
            fgets(buf, sizeof(buf), stdin);
            size_t len = strlen(buf);
            ret = send(socket_fd, buf, len, 0);         //向服务端发送消息
            if(-1 == ret)
            {
                perror("send error");
                return -1;
            }

        }
    }
    else                                                        //该进程为子进程，用于接收服务端发送的消息
    {
        while(true)
        {
            memset(buf, 0, sizeof(buf));
            ret = recv(socket_fd, buf, sizeof(buf), 0);         //接收客户端的消息
            if(-1 == ret)
            {
                perror("recv error");
                return -1;
            }

            printf("Received the message sent by the server: %s", buf);

        }
    }
    



    ret = close(socket_fd);
    if(-1 == ret)
    {
        perror("close error");
        return -1;
    }


    return 0;
}